package com.ruoyi.system.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.ruoyi.common.core.utils.HttpUtil;
import com.ruoyi.common.core.utils.ip.IpUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.system.domain.CaseHistory;
import com.ruoyi.system.domain.Drug;
import com.ruoyi.system.domain.DrugModel;
import com.ruoyi.system.domain.DrugRule;
import com.ruoyi.system.domain.vo.CaseHistoryVo;
import com.ruoyi.system.domain.vo.MatchVo;
import com.ruoyi.system.domain.vo.VerifyVo;
import com.ruoyi.system.service.*;
import com.ruoyi.system.utils.RedisToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Objects;

@RestController
@RequestMapping("/openApi")
public class VerifyController {

    private static final Logger log = LoggerFactory.getLogger(VerifyController.class);


    @Autowired
    private IDrugVerifyService drugVerifyService;

    @Autowired
    private IDrugRuleService drugRuleService;

    @Autowired
    private ICaseHistoryService caseHistoryService;

    @Autowired
    private IDrugService drugService;

    @Value("${whitelist}")
    private String whitelist;

    @Autowired
    private RedisToken redisToken;

    @Autowired
    private IDrugModelService drugModelService;

    @Value("${drug.match.ai.url}")
    private String aiMatchUrl;

    @PostMapping("/verify")
    public AjaxResult verify(@RequestBody VerifyVo verify, HttpServletRequest request)
    {
        String token = request.getHeader(RedisToken.TOKEN_NAME);

        if (! StringUtils.hasText(token)) {
            return new AjaxResult(401,"没传token", null);
        }

        try{
            if (redisToken.isTokenExpired(token)) {
                return new AjaxResult(401,"token过期", null);
            }

            //验证token
            String reqIp  = IpUtils.getIpAddr(request);

            String tokenIp = redisToken.getIpFromToken(request);

            if (!Objects.equals(reqIp, tokenIp)) {
                return new AjaxResult(401,"非法token", null);
            }

        } catch (Exception e) {
            return new AjaxResult(401,"token过期", null);
        }

        Drug drug = drugService.selectDrugByName(verify.getDrugName());
        if(drug == null){
            return AjaxResult.success(verify.getDrugName() + ",不存在!");
        }

        if("LR".equals(verify.getModelType()) || "RF".equals(verify.getModelType()) || "GBDT".equals(verify.getModelType())){

            //查询 编码
            Integer type = "LR".equals(verify.getModelType()) ? 1 : "RF".equals(verify.getModelType()) ? 3 : 4;
            DrugModel drugModel = drugModelService.selectDrugModel(type,verify.getDrugName());
            MatchVo match = new MatchVo();

            match.setText(verify.getContent());
            match.setModel(drugModel.getCode());
            try {
                String result = HttpUtil.doPost(aiMatchUrl, JSON.toJSON(match));
                JSONObject json = JSON.parseObject(result);
                Map<String,Object> resultMap = Maps.newHashMap();

                resultMap.put("result",json.getBooleanValue("result"));
                resultMap.put("detail",json.getJSONArray("details"));
                return AjaxResult.success(resultMap);
            }catch (Exception e){
                return new AjaxResult(200,"接口异常", null);
            }
        }

        DrugRule rule = drugRuleService.selectDrugRuleByDrugId(drug.getId());
        if(rule == null){
            return AjaxResult.success(verify.getDrugName() + ",暂无设置规则引擎!");
        }
        verify.setDrugRuleId(rule.getId());
        Map<String,Object> expression = drugRuleService.verify(verify);

        return AjaxResult.success(expression);
    }

    @GetMapping("/getToken")
    public AjaxResult getToken(String appSecret, HttpServletRequest request){

        String ip  = IpUtils.getIpAddr(request);
        if(whitelist.indexOf(ip) < 0){
            log.info("whitelist:"+ ip);
            log.info("ip:"+ ip);
            return AjaxResult.error("ip不在白名单内");
        }

        String token = redisToken.createToken(ip);
        return AjaxResult.success("成功",token);
    }

    @PostMapping("/match")
    public AjaxResult match(@RequestBody CaseHistoryVo caseHistory, HttpServletRequest request)
    {
        String token = request.getHeader(RedisToken.TOKEN_NAME);

        if (! StringUtils.hasText(token)) {
            return new AjaxResult(401,"没传token", null);
        }
        try{
            if (redisToken.isTokenExpired(token)) {
                return new AjaxResult(401,"token过期", null);
            }

            //验证token
            String reqIp  = IpUtils.getIpAddr(request);

            String tokenIp = redisToken.getIpFromToken(request);

            if (!Objects.equals(reqIp, tokenIp)) {
                return new AjaxResult(401,"非法token", null);
            }

        } catch (Exception e) {
            return new AjaxResult(401,"token过期", null);
        }

        Drug drug = drugService.selectDrugByName(caseHistory.getDrugName());
        if(drug == null){
            return AjaxResult.success(caseHistory.getDrugName() + ",不存在!");
        }

        DrugRule rule = drugRuleService.selectDrugRuleByDrugId(drug.getId());
        if(rule == null){
            return AjaxResult.success(caseHistory.getDrugName() + ",暂无设置规则引擎!");
        }

        CaseHistory ch = new CaseHistory();
        BeanUtils.copyProperties(caseHistory,ch);
        Long caseHistoryId = caseHistoryService.insertCase(ch);

        VerifyVo verify = new VerifyVo();
        verify.setAdmissionId(caseHistoryId);
        verify.setDrugRuleId(rule.getId());
        Map<String,Object> expression = drugRuleService.verify(verify);

        return AjaxResult.success(expression);
    }
}
